package tum0r.image;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * ClassName: ImageBase
 * Author: tum0r
 * Time: 2020/4/11 11:54
 */
public abstract class ImageBase {

    /**
     * 根据图片路径获取图片的BufferedImage对象
     *
     * @param imagePath 图片路径
     * @return 图片的BufferedImage对象
     * @throws IOException
     */
    public BufferedImage getImage(String imagePath) throws IOException {
        return getImage(new File(imagePath));
    }

    /**
     * 根据File对象获取图片的BufferedImage对象
     *
     * @param imageFile 图片的File对象
     * @return 图片的BufferedImage对象
     * @throws IOException
     */
    public BufferedImage getImage(File imageFile) throws IOException {
        BufferedImage result = null;
        if (imageFile != null && imageFile.exists() && imageFile.isFile() && imageFile.canRead()) {
            result = ImageIO.read(imageFile);
        }
        return result;
    }

    /**
     * 按指定的比例缩放图片（相对于原始图片），注意低分辨率图片放大到高分辨率会失真
     *
     * @param image 要缩放的图片的BufferedImage对象
     * @param scale 要缩放的比例
     * @return 缩放后的图片BufferedImage对象
     * @throws IOException
     */
    public BufferedImage zoom(BufferedImage image, double scale) throws IOException {
        BufferedImage result = null;
        if (image != null) {
            int width = (int) (image.getWidth() * scale);
            int height = (int) (image.getHeight() * scale);
            result = zoom(image, width, height);
        }
        return result;
    }

    /**
     * 按指定的宽度和高度缩放图片，注意低分辨率图片放大到高分辨率会失真
     *
     * @param image  要缩放的图片的BufferedImage对象
     * @param width  缩放后的图片宽度
     * @param height 缩放后的图片高度
     * @return 缩放后的图片BufferedImage对象
     * @throws IOException
     */
    public BufferedImage zoom(BufferedImage image, int width, int height) throws IOException {
        BufferedImage result = null;
        if (image != null) {
            result = new BufferedImage(width, height, image.getType());
            result.getGraphics().drawImage(image.getScaledInstance(width, height, Image.SCALE_SMOOTH), image.getMinX(), image.getMinY(), null);
        }
        return result;
    }

    /**
     * 处理图片，使图片对象更改为其他颜色类型，例如灰度化、二值化等等
     *
     * @param image 要处理的图片BufferedImage对象
     * @param type  处理后的图片对象颜色类型
     * @return 处理后的图片BufferedImage对象
     */
    public BufferedImage changeImageType(BufferedImage image, int type) {
        BufferedImage result = null;
        if (image != null) {
            int width = image.getWidth();
            int height = image.getHeight();
            result = new BufferedImage(width, height, type);
            result.getGraphics().drawImage(image.getScaledInstance(width, height, Image.SCALE_SMOOTH), image.getMinX(), image.getMinY(), null);
        }
        return result;
    }

    /**
     * 灰度化图片
     *
     * @param image 要灰度化的图片BufferedImage对象
     * @return 灰度化后的图片BufferedImage对象
     */
    public BufferedImage gray(BufferedImage image) {
        return changeImageType(image, BufferedImage.TYPE_USHORT_GRAY);
    }

    /**
     * 二值化图片
     *
     * @param image 要二值化的图片BufferedImage对象
     * @return 二值化后的图片BufferedImage对象
     */
    public BufferedImage binary(BufferedImage image) {
        return changeImageType(image, BufferedImage.TYPE_BYTE_BINARY);
    }

    /**
     * 根据图片的路径获取图片并处理图片
     *
     * @param imagePath 要处理的图片的路径
     * @return 处理后的图片BufferedImage对象
     * @throws IOException
     */
    public BufferedImage handle(String imagePath) throws IOException {
        return handle(getImage(imagePath));
    }

    /**
     * 根据图片的File对象获取图片并处理图片
     *
     * @param imageFile 要处理的图片的File对象
     * @return 处理后的图片BufferedImage对象
     * @throws IOException
     */
    public BufferedImage handle(File imageFile) throws IOException {
        return handle(getImage(imageFile));
    }

    /**
     * 处理图片，延迟到子类实现具体功能
     *
     * @param image 要处理的图片BufferedImage对象
     * @return 处理后的图片BufferedImage对象
     * @throws IOException
     */
    public abstract BufferedImage handle(BufferedImage image);

    /**
     * 保存图片到文件，默认为程序运行文件夹下的result.png
     *
     * @param image      图片的BufferedImage对象
     * @param outputPath 图片的保存路径，为null、空和文件夹时默认为result.png
     * @throws IOException
     */
    public void saveImage(BufferedImage image, String outputPath) throws IOException {
        if (image != null) {
            String type = "png";
            String path = "result.png";
            if (outputPath != null) {
                if (outputPath.lastIndexOf(".") != -1 && outputPath.lastIndexOf(".") < outputPath.length() - 1) {
                    type = outputPath.substring(outputPath.lastIndexOf(".") + 1);
                    path = outputPath;
                } else if (new File(outputPath).isDirectory()) {
                    path = outputPath + File.separator + "result.png";
                }
            }
            ImageIO.write(image, type, new File(path));
        }
    }

}
